export interface ArrayToTreeProps {
    data: any[];
    parentId: number;
    props?: {
        id?: string;
        parentId?: string;
        children?: string;
    };
    render?: (record: any) => void;
}

export const publicDealTree = (
    data: any[],
    props = {
        sourceKey: 'id',
        sourceName: 'label',
        targetKey: 'key',
        targetName: 'title',
        children: 'children',
    },
) => {
    return data.map((item: any) => {
        const nItem: any = {};
        nItem[props.targetKey] = item[props.sourceKey];
        nItem[props.targetName] = item[props.sourceName];
        if (nItem[props.children] && nItem[props.children].length) {
            nItem[props.children] = publicDealTree(
                nItem[props.children],
                props,
            );
        }
        return nItem;
    });
};

/**
 * 在树结构中查找目标节点及其所有父节点路径
 * @param {Array} tree 树数据
 * @param {*} targetValue 目标字段值
 * @param {string} [field='id'] 匹配字段名，默认 'id'
 * @param {string} [childrenKey='children'] 子节点字段名，默认 'children'
 * @returns {Array|null} 节点路径数组，未找到返回 null
 */
export function findNodePath(
    tree: any,
    targetValue: any,
    field = 'id',
    childrenKey = 'children',
) {
    // 辅助递归函数
    const findPath = (node: any, currentPath: any) => {
        const path = [...currentPath, node];

        // 当前节点匹配目标值
        if (node[field] === targetValue) return path;

        // 递归遍历子节点
        for (const child of node[childrenKey] || []) {
            const result: any = findPath(child, path);
            if (result) return result;
        }

        return null;
    };

    // 遍历根节点
    for (const node of tree) {
        const path = findPath(node, []);
        if (path) return path;
    }

    return null;
}

export const publicArrayToTree = (options: ArrayToTreeProps) => {
    const { data, parentId, props, render } = options;
    if (!data.length) return [];
    const id: any = props && props.id ? props.id : 'id';
    const parentIdKey: any =
        props && props.parentId ? props.parentId : 'parentId';
    const childrenKey: any =
        props && props.children ? props.children : 'children';
    const tree: any[] = [];
    for (let i = 0; i < data.length; i++) {
        const node: any = data[i];
        if (node[parentIdKey] === parentId) {
            const children = publicArrayToTree({
                data,
                parentId: node[id],
                props,
                render,
            });
            if (children.length > 0) {
                node[childrenKey] = children;
            } else {
                delete node[childrenKey];
            }
            render && render(node);
            tree.push(node);
        }
    }
    return tree;
};

export function publicFilterEmptyField(list: any) {
    const obj: any = {};
    Object.keys(list).forEach((ele: any) => {
        if (list[ele] || list[ele] === 0) {
            obj[ele] = list[ele];
        }
    });
    return obj;
}

export const publicFormatTime = (time: Date | number | string, fmt: string) => {
    if (!time) return "";
    else {
        const date = new Date(time);
        const o: any = {
            "M+": date.getMonth() + 1,
            "d+": date.getDate(),
            "H+": date.getHours(),
            "m+": date.getMinutes(),
            "s+": date.getSeconds(),
            "q+": Math.floor((date.getMonth() + 3) / 3),
            S: date.getMilliseconds()
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(
                RegExp.$1,
                (date.getFullYear() + "").substr(4 - RegExp.$1.length)
            );
        }
        for (const k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(
                    RegExp.$1,
                    RegExp.$1.length === 1
                        ? o[k]
                        : ("00" + o[k]).substr(("" + o[k]).length)
                );
            }
        }
        return fmt;
    }
};
